package com.gzhryc.shared_device.oem.code.user.services;

import com.gzhryc.common.IDTools;
import com.gzhryc.common.StringTools;
import com.gzhryc.common.data.ValidateTools;
import com.gzhryc.common.exceptions.LogicException;
import com.gzhryc.common.logging.Logger;
import com.gzhryc.common.secruity.EncryptTools;
import com.gzhryc.jdbc.Conditions;
import com.gzhryc.jdbc.JdbcSession;
import com.gzhryc.jdbc.MultiDBTools;
import com.gzhryc.shared_device.base.IUserService;
import com.gzhryc.shared_device.oem.code.agent.services.AgentRelationService;
import com.gzhryc.shared_device.oem.code.agent.services.AgentService;
import com.gzhryc.shared_device.oem.code.place.services.PlaceProfitUserService;
import com.gzhryc.shared_device.oem.code.user.dao.UserDao;
import com.gzhryc.shared_device.oem.code.user.dao.db.User;
import com.gzhryc.shared_device.oem.code.user.services.dto.UserSearch;

import java.sql.SQLException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class UserService implements IUserService{

    static Logger log = Logger.getLogger(UserService.class);

    public static UserService self() {
        return MultiDBTools.getService(UserService.class, true);
    }

    public static UserService self(String jdbcKey) {
        return MultiDBTools.getService(jdbcKey, UserService.class, true);
    }

    UserDao dao;

    public UserService(String jdbcKey) {
        this.dao = new UserDao(jdbcKey);
    }

    public List<User> findBySearch(UserSearch search, Integer pageNo, Integer pageLimit){
        Conditions conditions = dao.buildConditions(search);
        conditions.and().likeBoth("nickname",search.getTrim()).or()
                .likeBoth("name",search.getTrim()).or().likeBoth("phone",search.getTrim());
        conditions.desc("createDate");
        try {
            return dao.findByCondition(conditions,pageNo,pageLimit);
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        return null;
    }

    public List<User> findByUserIds(List<Long> userIds){
        if(userIds != null && userIds.size() > 0){
            Conditions conditions = new Conditions(User.class);
            conditions.and().in("id",userIds);
            try {
                return dao.findByCondition(conditions);
            } catch (SQLException e) {
                log.error(e.getMessage(),e);
            }
        }
        return null;
    }

    public Long countBySearch(UserSearch search){
        Conditions conditions = dao.buildConditions(search);
        conditions.and().likeBoth("nickname",search.getTrim()).or()
                .likeBoth("name",search.getTrim()).or().likeBoth("phone",search.getTrim());
        try {
            return dao.count(conditions);
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        return 0L;
    }

    public User getById(Long id){
        try {
            return dao.getById(id);
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        return null;
    }

    public User getByExId(String appId,String openId){
        if(StringTools.isNotBlank(appId) && StringTools.isNotBlank(openId)) {
            Conditions conditions = new Conditions(User.class);
            conditions.and().is("appId",appId);
            conditions.and().is("openId",openId);

            try {
                return dao.get(conditions);
            } catch (SQLException e) {
                log.error(e.getMessage(), e);
            }
        }
        return null;
    }

    public User getByLoginToken(String loginToken) {
    	if(StringTools.isNotBlank(loginToken)) {
    		Conditions condition = new Conditions(User.class);
    		condition.and().is("loginToken", loginToken);
    		
    		try {
				return dao.get(condition);
			} catch (SQLException e) {
				log.error(e.getMessage(), e);
			}
    	}
    	return null;
    }
    
    public User getByPhone(String phone){
        if(StringTools.isNotBlank(phone)){
            Conditions conditions = new Conditions(User.class);
            conditions.and().is("phone",phone);
            try {
                return dao.get(conditions);
            } catch (SQLException e) {
                log.error(e.getMessage(),e);
            }
        }
        return null;
    }

    public User login(String phone,String loginPwd){
        if(StringTools.isNotBlank(phone) && StringTools.isNotBlank(loginPwd)) {
            User user = getByPhone(phone);
            if (user != null && EncryptTools.md5(loginPwd).equals(user.getLoginPwd())) {
            	String token = IDTools.getUUID();
            	int count = 0;
				while(count < 3 && this.getByLoginToken(token) != null) {
					token = IDTools.getUUID();
					count++;
				}
				if(count < 3) {
	            	User updateEntity = new User();
	            	updateEntity.setId(user.getId());
	            	updateEntity.setLoginToken(token);
	            	updateEntity.setLastLoginDate(new Date());
	            	
	            	try {
						if(dao.updateNotNull(updateEntity) > 0) {
							user.setLoginToken(updateEntity.getLoginToken());
							user.setLastLoginDate(updateEntity.getLastLoginDate());
							return user;
						}
					} catch (SQLException e) {
						log.error(e.getMessage(), e);
					}
				}
            }
        }
        return null;
    }

    public void logout(Long id) {
		if(id != null) {
			Map<String,Object> data = new HashMap<String,Object>();
			data.put("id", id);
			data.put("loginToken", null);
			
			try {
				dao.update(data);
			} catch (SQLException e) {
				log.error(e.getMessage(), e);
			}
		}
	}
    
    public boolean updateLastLoginType(Long id,String lastLoginType){
        if(id != null && StringTools.isNotBlank(lastLoginType)){
            User updateEntity = new User();
            updateEntity.setId(id);
            updateEntity.setLastLoginType(lastLoginType);
            updateEntity.setLastLoginDate(new Date());
           
            try {
                return dao.updateNotNull(updateEntity) > 0;
            } catch (SQLException e) {
                log.error(e.getMessage(),e);
            }
        }
        return false;
    }

    public boolean add(User user) throws LogicException {
        //检查用户手机号是否正确
        if(!ValidateTools.isPhone(user.getPhone())){
            throw new LogicException("请填写正确的手机号");
        }
        User temp = getByPhone(user.getPhone());
        if(temp != null){
            throw new LogicException("手机号已存在");
        }
        if(StringTools.isBlank(user.getNickname()) && StringTools.isBlank(user.getName())){
            throw new LogicException("请填写用户姓名或昵称");
        }
        if(StringTools.isBlank(user.getNickname())){
            user.setNickname(user.getName());
        }
        if(StringTools.isBlank(user.getName())){
            user.setName(user.getNickname());
        }
        user.setCreateDate(new Date());
        try {
            if(dao.insert(user) > 0){
                return true;
            }
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        return false;
    }

    public boolean updateLoginPwd(Long id,String loginPwd) throws LogicException{
        if(id != null && StringTools.isNotBlank(loginPwd)) {
            User user = new User();
            user.setId(id);
            user.setLoginPwd(EncryptTools.md5(loginPwd));

            try {
                return dao.updateNotNull(user) > 0;
            } catch (SQLException e) {
                log.error(e.getMessage(), e);
            }
        }
        return false;
    }

    public boolean updateNotNull(User user) throws LogicException {
        //检查用户手机号是否正确
        if(StringTools.isNotBlank(user.getPhone())) {
            if (!ValidateTools.isPhone(user.getPhone())) {
                throw new LogicException("请填写正确的手机号");
            }
        }
        try {
            return dao.updateNotNull(user) > 0;
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        return false;
    }

    public boolean deleteById(Long id) throws LogicException {
        if(AgentService.self().getByUserId(id) != null){
            throw new LogicException("用户是代理，请先删除代理信息");
        }
        if(AgentRelationService.self().countByRelationUserId(id) > 0){
            throw new LogicException("用户存在代理关系，请先删除");
        }
        Long total = PlaceProfitUserService.self().countByUserId(id);
        if(total != null && total > 0){
            throw new LogicException("用户存在网点分成信息，请先删除");
        }
        JdbcSession.begin();
        try {
            if(dao.deleteById(id) > 0){
                if(UserWalletService.self().deleteByUserId(id)){
                    JdbcSession.commit();
                    return true;
                }
            }
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        } finally {
            JdbcSession.end();
        }
        return false;
    }
}
